package com.rayboot.footpoint.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SyncFailedException;
import java.nio.channels.FileChannel;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.R.integer;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.widget.Toast;

import com.rayboot.footpoint.R;
import com.rayboot.footpoint.model.Footprint;
import com.rayboot.footpoint.utils.camera.FootprintImageManager;
import com.rayboot.footpoint.utils.voice.FootprintVoiceManager;

public class Util {
	private static ImageFileNamer sImageFileNamer;

	public static void initialize(Context context) {
		sImageFileNamer = new ImageFileNamer(
				context.getString(R.string.image_file_name_format));
	}

	public static String createJpegName(long dateTaken) {
		synchronized (sImageFileNamer) {
			return sImageFileNamer.generateName(dateTaken);
		}
	}

	private static class ImageFileNamer {
		private SimpleDateFormat mFormat;

		// The date (in milliseconds) used to generate the last name.
		private long mLastDate;

		// Number of names generated for the same second.
		private int mSameSecondCount;

		public ImageFileNamer(String format) {
			mFormat = new SimpleDateFormat(format);
		}

		public String generateName(long dateTaken) {
			Date date = new Date(dateTaken);
			String result = mFormat.format(date);

			// If the last name was generated for the same second,
			// we append _1, _2, etc to the name.
			if (dateTaken / 1000 == mLastDate / 1000) {
				mSameSecondCount++;
				result += "_" + mSameSecondCount;
			} else {
				mLastDate = dateTaken;
				mSameSecondCount = 0;
			}

			return result;
		}
	}

	public static void showToast(Context context, int res) {
		Toast.makeText(context, res, Toast.LENGTH_SHORT).show();
	}

	public static String getDefaultName(Context context) {
		DecimalFormat localDecimalFormat = new DecimalFormat(" ##000");
		int i = SettingInfo.getInstance(context).getNewSerialNumber();
		return "Footprints " + localDecimalFormat.format(i);
	}

	public static boolean checkAudioData(Footprint footprint) {
		if (footprint == null || footprint.mAudioPath == null
				|| footprint.mAudioPath.equalsIgnoreCase("")
				|| !new File(footprint.mAudioPath).exists()) {
			return false;
		}
		return true;
	}

	public static void setLocationToPicture(Footprint footpoint)
			throws IOException {
		if (footpoint == null) {
			return;
		}

		ExifInterface ei = new ExifInterface(footpoint.mPicPath);
		double dLatitude = footpoint.mLatitude / 1000000.0D;
		double dLongitude = footpoint.mLongitude / 1000000.0D;
		ei.setAttribute(ExifInterface.TAG_GPS_LATITUDE,
				makeLatLongString(dLatitude));
		ei.setAttribute(ExifInterface.TAG_GPS_LONGITUDE,
				makeLatLongString(dLongitude));
		ei.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF,
				makeLatStringRef(dLatitude));
		ei.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF,
				makeLonStringRef(dLatitude));
	}

	public static String makeLatLongString(double position) {
		double d1 = Math.abs(position);
		int i = (int) d1;
		double d2 = d1 - i;
		int j = (int) (d2 * 60.0D);
		int k = (int) (1000.0D * (60.0D * (d2 * 60.0D - j)));
		return i + "/1," + j + "/1," + k + "/1000";
	}

	public static String makeLatStringRef(double position) {
		return position > 0.0D ? "N" : "S";
	}

	public static String makeLonStringRef(double position) {
		return position > 0.0D ? "W" : "E";
	}

	public static void forceSync(final ContentResolver contentResolver,
			final String fileName) {
		new Thread(new Runnable() {
			public void run() {
				try {
					Uri uri = Uri.fromFile(new File(FootprintImageManager
							.getDirectory() + File.separator + fileName));
					ParcelFileDescriptor parcelFileDescriptor = contentResolver
							.openFileDescriptor(uri, "r");
					parcelFileDescriptor.getFileDescriptor().sync();
					parcelFileDescriptor.close();
					return;
				} catch (FileNotFoundException e) {
					Log.e("FootprintUtils", "forceSync FileNotFoundException "
							+ e);
				} catch (SyncFailedException e) {
					Log.e("FootprintUtils", "forceSync SyncFailedException "
							+ e);
				} catch (IOException e) {
					Log.e("FootprintUtils", "forceSync IOException " + e);
				}
			}
		}).start();
	}

	public static void touchSDFile() {
		File[] arrayOfFile = new File[3];
		arrayOfFile[0] = new File(StorageUtil.getFootprintStorageDirectory());
		arrayOfFile[1] = new File(FootprintImageManager.getDirectory());
		arrayOfFile[2] = new File(FootprintVoiceManager.getDirectory());
		for (File file : arrayOfFile) {
			if (!file.exists()) {
				file.mkdir();
			}
		}
	}

	public static String getDBPathOnSD() {
		return StorageUtil.getFootprintStorageDirectory() + File.separator
				+ "footpoints.db";
	}

	public static int getExtDBVersion() {
		int i = -1;
		File localFile = new File(getDBPathOnSD());
		SQLiteDatabase localSQLiteDatabase = null;
		try {
			if ((localFile != null) && (localFile.exists())
					&& (localFile.length() > 0L)) {
				localSQLiteDatabase = SQLiteDatabase.openDatabase(
						getDBPathOnSD(), null, 1);
				i = localSQLiteDatabase.getVersion();
			}
		} catch (SQLiteException localSQLiteException) {
			localSQLiteDatabase.close();
		} finally {
			localSQLiteDatabase.close();
		}
		return i;
	}

	public static boolean copyFile(File paramFile1, File paramFile2) {
		if ((paramFile1 == null) || (!paramFile1.exists())
				|| (paramFile2 == null)) {
			return false;
		}
		FileChannel localFileChannel1 = null;
		FileChannel localFileChannel2 = null;
		try {
			localFileChannel1 = new FileInputStream(paramFile1).getChannel();
			FileOutputStream localFileOutputStream = new FileOutputStream(
					paramFile2);
			localFileChannel2 = localFileOutputStream.getChannel();
			localFileChannel2.transferFrom(localFileChannel1, 0L,
					localFileChannel1.size());
			localFileOutputStream.getFD().sync();
			try {
				if (localFileChannel1 != null) {
					localFileChannel1.close();
				}
				if (localFileChannel2 == null) {
					localFileChannel2.close();
				}
			} catch (IOException localIOException6) {

			}
		} catch (Exception localException) {
			Log.e("FootprintUtils", localException.getMessage(), localException);
			try {
				if (localFileChannel1 != null) {
					localFileChannel1.close();
				}
				if (localFileChannel2 == null) {
					localFileChannel2.close();
				}
			} catch (IOException localIOException4) {
				Log.w("FootprintUtils", localIOException4.getMessage(),
						localIOException4);
			}
		} finally {
			try {
				if (localFileChannel1 != null) {
					localFileChannel1.close();
				}
				if (localFileChannel2 == null) {
					localFileChannel2.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return true;
	}

	public static Drawable boundCenterBottom(Drawable drawable) {
		int width = drawable.getIntrinsicWidth();
		int half_width = width / 2;
		int height = drawable.getIntrinsicHeight();
		drawable.setBounds(-half_width, 1 - height, width - half_width, 1);
		return drawable;
	}
}
